#include "ThreadPool.h"
#include "Thread.h"
#include <unistd.h>

ThreadPool::ThreadPool(size_t threadNum, size_t queSize)
: _threadNum(threadNum)
, _queSize(queSize)
, _taskQue(_queSize)
, _isExit(false){}


ThreadPool::~ThreadPool(){}


// 线程池的启动
void ThreadPool::start(){
    // 1. 将子线程创建出来, 并且存放在 vector
    for(size_t idx = 0; idx < _threadNum; ++idx){
        //=====================新加=========================多了个名字
        unique_ptr<Thread> up(new Thread(std::bind(&ThreadPool::threadFunc, this), std::to_string(idx)));
        _threads.push_back(std::move(up));
    }

    // 2. 遍历 vector, 然后将子线程全部运行起来
    for(auto &th : _threads){
        th->start();
    }
}


void ThreadPool::stop(){
    // 如果任务队列中还有任务, 那么工作线程是不能退出来的
    while(!_taskQue.empty()){
        sleep(1);
    }

    // 1. 遍历vector, 然后将子线程全部停止运行
    _isExit = true;

    // 将所有睡眠在 _notEmpty 上的线程唤醒
    _taskQue.wakeup();
    for(auto &th : _threads){
        th->join();
    }

}


// 添加任务与获取任务
void ThreadPool::addTask(Task &&task){
    if(task){
        _taskQue.push(std::move(task));
    }
}


Task ThreadPool::getTask(){
    return _taskQue.pop();
}


// 线程池交给子线程做的任务
void ThreadPool::threadFunc(){
    while(!_isExit){
        Task taskcb = getTask();
        if(taskcb){
            taskcb();// 执行任务
        }
    }
}
